package com.tao.mytestdd.datagrama

import com.google.gson.GsonBuilder
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.ObjectInputStream
import java.io.ObjectOutputStream
import java.lang.StringBuilder
import java.net.DatagramPacket
import java.net.DatagramSocket
import java.net.InetAddress

/**
 * reate by tao on{DATE}
 */
class UDPSendManager {
    var packageLen = 60000
    var socket: DatagramSocket? = null;
    var sessionTime = 60
    var local_service_host: String = "127.0.0.1"
    var local_service_port: Int = 8080
    var dataSeccession = "session"
    val clientMap = HashMap<String, HostConf>()

    fun registerClient(name: String, host: String, port: Int) {
        clientMap[name] = HostConf(host, port)
    }

    fun removeClient(name: String) {
        if (clientMap.containsKey(name))
            clientMap.remove(name)
    }

    constructor()

    constructor(socket: DatagramSocket?) {
        this.socket = socket
    }

    constructor(local_service_host: String, local_service_port: Int) {
        this.local_service_host = local_service_host
        this.local_service_port = local_service_port
    }


    fun sendData(data: ByteArray, host: String, port: Int) {
        this.socket?.let {
            sendData(it, data, host, port)
        } ?: let {
            sendData(DatagramSocket(), data, host, port)
        }
    }

    private fun sendData(socket: DatagramSocket, data: ByteArray, host: String, port: Int) {
        socket.send(DatagramPacket(data, 0, data.size, InetAddress.getByName(host), port))

    }

    fun sendMag(msg: String, client: String) {
        clientMap[client]?.let { sendMag(msg, it) }
    }


    fun sendMag(msg: String, conf: HostConf) {
        sendMag(msg, conf.host, conf.port)
    }

    fun sendMag(msg: String, host: String, port: Int) {
        sendMag(msg, host, port, false)
    }

    fun sendMag(msg: String, host: String, port: Int, server: Boolean) {
        val dataList = createPackageDatas(msg, local_service_host, local_service_port, server)
        dataList.forEach {
            sendData(it, host, port)
            try {
                val toLong = (it.toUByteArray().size / 1000 + it.toUByteArray().size % 100).toLong()
                System.err.println("间隔 time:$toLong")
                Thread.sleep(toLong)
            } catch (e: Exception) {
            }
        }
    }

    private fun createPackageDatas(
        msg: String,
        local_host: String,
        local_port: Int
    ): MutableList<ByteArray> {
        return createPackageDatas(msg, local_host, local_port, false)
    }

    private fun createPackageDatas(
        msg: String,
        local_host: String,
        local_port: Int,
        server: Boolean
    ): MutableList<ByteArray> {
        return createPackageDatas(msg.toByteArray(), local_host, local_port, server)
    }

    private fun createPackageDatas(
        msgBytes: ByteArray,
        local_host: String,
        local_port: Int
    ): MutableList<ByteArray> {
        return createPackageDatas(msgBytes, local_host, local_port, false)
    }

    private fun createPackageDatas(
        msgBytes: ByteArray,
        local_host: String,
        local_port: Int,
        server: Boolean
    ): MutableList<ByteArray> {

        val dataList = mutableListOf<ByteArray>()

        for (i in msgBytes.indices step packageLen) {
            val dataEntity = DataEntity<Any?>()
            val len = if ((i + packageLen) >= msgBytes.size) msgBytes.size - i else packageLen
            val data = ByteArray(len)
            System.arraycopy(msgBytes, i, data, 0, data.size)
            dataEntity.objBytes = data
            dataEntity.host = local_host
            dataEntity.port = local_port
            dataEntity.pckageCount =
                msgBytes.size / packageLen + (if (msgBytes.size % packageLen > 0) 1 else 0)
            dataEntity.index = i
            dataEntity.timeStamp = System.currentTimeMillis()
            dataEntity.sessionTime = sessionTime
            dataEntity.packageTag = msgBytes.hashCode()
            dataEntity.packageVaildTime = 5 * 60 * 1000
            dataEntity.session = dataSeccession
            dataEntity.fromServer = server

            val byteArrayOutputStream = ByteArrayOutputStream()
            val objectOutputStream = ObjectOutputStream(byteArrayOutputStream)
            objectOutputStream.writeObject(dataEntity)

            System.err.println(" 数据长度：" + data.size)
            try {
                dataList.add(byteArrayOutputStream.toByteArray())
            } finally {
                objectOutputStream.close()
                byteArrayOutputStream.close()
            }
        }

        return dataList

    }


    fun sendAll(msg: String) {
        clientMap.keys.forEach {
            sendMag(msg, it)
            try {
                Thread.sleep(10)
            } catch (e: Exception) {
            }
        }
    }

    companion object {
        @JvmStatic
        fun main(args: Array<String>) {
//            val udpSendManager = UDPSendManager("192.168.0.98", 6667)
//            val msg = createMsg(18000)
//            val dataEntity = UDPSendManager().createPackageDatas(msg, "192.168.0.104", 6665)
//            System.err.println(msg.toByteArray().size)
//
//
//            var buff = ByteArray(0)
//            var len = 0
//
//            dataEntity.forEach {
//
//                val entity =
//                    ObjectInputStream(ByteArrayInputStream(it)).readObject() as DataEntity<ByteArray>
//
////                val entity = gson.fromJson(it, object : TypeToken<DataEntity<ByteArray>>() {}.type) as DataEntity<ByteArray>
//                System.err.println("lenth:" + entity.objBytes.size)
//                val bf = ByteArray(buff.size + entity.objBytes.size)
//                System.arraycopy(buff, 0, bf, 0, buff.size)
//                System.arraycopy(entity.objBytes, 0, bf, buff.size, entity.objBytes.size)
//                buff = bf
//            }
//            val str = String(buff)
//            System.err.println(str.length)

            val str = createMsg(1024 * 1024)
            System.err.println("  ${str.length}  ${str.toByteArray().size}")

        }

        val str = "qwerty傻加安全我的家我打的骄傲大哈哈返回偶发ghjkl;'zxcvbnm,1234456789去是撒多大1去撒二分法龙角散"

        @JvmStatic
        fun createMsg(count: Int): String {

            val sb = StringBuilder()
            for (i in 0 until count / str.length) {
                if (sb.length + str.length < count) {
                    sb.append(str)
                }
            }
            if (count - sb.length > 0) {
                sb.append(str.subSequence(0, count - sb.length))
            }
            return sb.toString()
        }


    }


    data class HostConf(var host: String = "", var port: Int = 80) {


    }
}